package httpserver

import (
	"encoding/json"
	"fmt"
	"log"
	httpclient "modbus-dtu-plugin/http_client"
	"modbus-dtu-plugin/modbus"
	"modbus-dtu-plugin/zaplog"
	"net/http"
	"os"

	"github.com/spf13/viper"
	"go.uber.org/zap"
)

func HttpServer() {
	http.HandleFunc("/api/form/config", GetFormConfig)                      //获取插件表单配置
	http.HandleFunc("/api/device/config/update", UpdateSubDeviceConfig)     //修改子设备配置
	http.HandleFunc("/api/device/config/add", AddSubDeviceConfig)           //新增子设备配置
	http.HandleFunc("/api/device/config/delete", DeleteSubDeviceConfig)     //删除子设备配置
	err := http.ListenAndServe(viper.GetString("http_server.address"), nil) //设置监听的端口
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

func ReadFormConfig() interface{} {
	filePtr, err := os.Open("./form_config.json")
	if err != nil {
		log.Println("文件打开失败...", err.Error())
		return nil
	}
	defer filePtr.Close()
	var info interface{}
	// 创建json解码器
	decoder := json.NewDecoder(filePtr)
	err = decoder.Decode(&info)
	if err != nil {
		log.Println("解码失败", err.Error())
		return info
	} else {
		log.Println("读取文件[form_config.json]成功...")
		return info
	}
}

func GetFormConfig(w http.ResponseWriter, r *http.Request) {
	r.ParseForm() //解析参数，默认是不会解析的
	log.Println("【收到api请求】path", r.URL.Path)
	log.Println("scheme", r.URL.Scheme)
	var rsp = make(map[string]interface{})
	rsp["data"] = ReadFormConfig()
	data, err := json.Marshal(rsp)
	if err != nil {
		log.Println(err.Error())
	}
	fmt.Fprint(w, string(data)) //这个写入到w的是输出到客户端的
}

type SubDeviceConfigStruct struct {
	DeviceType   string
	ParentId     string
	DeviceId     string
	DeviceConfig modbus.SubDevice
}

// 添加子设备配置
func AddSubDeviceConfig(w http.ResponseWriter, r *http.Request) {
	r.ParseForm() //解析参数，默认是不会解析的
	log.Println("【收到api请求】path", r.URL.Path)
	log.Println("scheme", r.URL.Scheme)
	log.Println(r.Method)
	if r.Method != "POST" {
		//w.WriteHeader(201)
		return
	}
	// 打印请求体
	var reqdata SubDeviceConfigStruct
	if err := json.NewDecoder(r.Body).Decode(&reqdata); err != nil {
		r.Body.Close()
		w.WriteHeader(400)
		return
	}
	log.Println("req json: ", reqdata)
	w.Header().Set("Content-Type", "application/json")
	var rspdata = make(map[string]interface{})
	rspdata["code"] = 200
	rspdata["message"] = "success"
	// 添加子设备需要将子设备配置添加到map中
	var gateway_id = reqdata.ParentId
	// 判断GatewayConn中是否存在该网关
	if _, ok := modbus.GatewayConn[gateway_id]; !ok {
		// 不存在，获取网关配置
		var req = httpclient.GetGatewayConfig{
			DeviceId: gateway_id,
		}
		rsp, err := httpclient.ApiGetGatewayConfig(req)
		if err != nil {
			zaplog.Logger.Error("get gateway config failed", zap.Error(err))
			rspdata["code"] = 400
			rspdata["message"] = "get gateway config failed"
		}
		var gateway_config modbus.Gateway
		err = json.Unmarshal(rsp, &gateway_config)
		if err != nil {
			zaplog.Logger.Error("json unmarshal failed", zap.Error(err))
			rspdata["code"] = 400
			rspdata["message"] = "json unmarshal failed"
		}
		//遍历网关配置
		for i := 0; i < len(gateway_config.SubDevice); i++ {
			gateway_config.SubDevice[i].DeviceConfig.GatewayId = gateway_config.Id
		}
		// 处理单个网关配置
		modbus.HandleGatewayConfig(gateway_config)

	} else {
		// 获取子设备的key
		var sub_device_key = fmt.Sprintf("%d_%d_%d", reqdata.DeviceConfig.DeviceConfig.DeviceAddress, reqdata.DeviceConfig.DeviceConfig.FunctionCode, reqdata.DeviceConfig.DeviceConfig.StartingAddress)
		modbus.GatewayConn[gateway_id].SubDeviceReqMap[sub_device_key] = reqdata.DeviceConfig
		//server_map.SubDeviceConfigMap[reqdata.DeviceId] = reqdata.DeviceConfig
		//重启连接
		modbus.GatewayConn[gateway_id].Disconnect()
		modbus.GatewayConn[gateway_id].ServerAddr = reqdata.DeviceConfig.DeviceConfig.ServerAddr
		modbus.GatewayConn[gateway_id].Connect()
	}
	//校验表单
	if reqdata.DeviceConfig.DeviceConfig.FunctionCode == uint8(1) {
		if len(reqdata.DeviceConfig.DeviceConfig.Key) > int(reqdata.DeviceConfig.DeviceConfig.AddressNum) {
			rspdata["code"] = 400
			rspdata["message"] = "属性别名数量与线圈数量不匹配！"
		}
	}
	data, err := json.Marshal(rspdata)
	if err != nil {
		log.Println(err.Error())
	}
	fmt.Fprint(w, string(data))
}

// 修改子设备配置
func UpdateSubDeviceConfig(w http.ResponseWriter, r *http.Request) {
	r.ParseForm() //解析参数，默认是不会解析的
	log.Println("【收到api请求】path", r.URL.Path)
	log.Println("scheme", r.URL.Scheme)
	log.Println(r.Method)
	if r.Method != "POST" {
		//w.WriteHeader(201)
		return
	}
	var reqdata SubDeviceConfigStruct
	if err := json.NewDecoder(r.Body).Decode(&reqdata); err != nil {
		r.Body.Close()
		w.WriteHeader(400)
		return
	}
	log.Println("req json: ", reqdata)

	//server_map.SubDeviceConfigMap[reqdata.DeviceId] = reqdata.DeviceConfig //修改子设备配置只需要修改map中的配置
	var rspdata = make(map[string]interface{})
	w.Header().Set("Content-Type", "application/json")
	rspdata["code"] = 200
	rspdata["message"] = "success"
	var gateway_id = reqdata.ParentId
	if _, ok := modbus.GatewayConn[gateway_id]; !ok {
		// 不存在，报错
		zaplog.Logger.Error("gateway not exist", zap.String("gateway_id", gateway_id))
		rspdata["code"] = 400
		rspdata["message"] = "gateway not exist"
	} else {
		// 获取子设备的key
		var sub_device_key = fmt.Sprintf("%d_%d_%d", reqdata.DeviceConfig.DeviceConfig.DeviceAddress, reqdata.DeviceConfig.DeviceConfig.FunctionCode, reqdata.DeviceConfig.DeviceConfig.StartingAddress)
		// 遍历map，将原来的key删除
		for key, subDevice := range modbus.GatewayConn[gateway_id].SubDeviceReqMap {
			if subDevice.DeviceConfig.DeviceId == reqdata.DeviceId {
				delete(modbus.GatewayConn[gateway_id].SubDeviceReqMap, key)
			}
		}
		// 将新的key添加到map中
		modbus.GatewayConn[gateway_id].SubDeviceReqMap[sub_device_key] = reqdata.DeviceConfig
		//重启连接
		modbus.GatewayConn[gateway_id].Disconnect()
		modbus.GatewayConn[gateway_id].ServerAddr = reqdata.DeviceConfig.DeviceConfig.ServerAddr
		modbus.GatewayConn[gateway_id].Connect()
	}
	//校验表单
	if reqdata.DeviceConfig.DeviceConfig.FunctionCode == uint8(1) {
		if len(reqdata.DeviceConfig.DeviceConfig.Key) > int(reqdata.DeviceConfig.DeviceConfig.AddressNum) {
			rspdata["code"] = 400
			rspdata["message"] = "属性别名数量与线圈数量不匹配！"
		}
	}
	data, err := json.Marshal(rspdata)
	if err != nil {
		log.Println(err.Error())
	}
	fmt.Fprint(w, string(data))
}

func DeleteSubDeviceConfig(w http.ResponseWriter, r *http.Request) {
	r.ParseForm() //解析参数，默认是不会解析的
	log.Println("【收到api请求】path", r.URL.Path)
	log.Println("scheme", r.URL.Scheme)
	log.Println(r.Method)
	if r.Method != "POST" {
		//w.WriteHeader(201)
		return
	}
	var reqdata SubDeviceConfigStruct
	if err := json.NewDecoder(r.Body).Decode(&reqdata); err != nil {
		r.Body.Close()
		w.WriteHeader(400)
		return
	}
	log.Println("req json: ", reqdata)
	var rspdata = make(map[string]interface{})
	w.Header().Set("Content-Type", "application/json")
	rspdata["code"] = 200
	rspdata["message"] = "success"
	//delete(server_map.SubDeviceConfigMap, reqdata.DeviceId) //修改子设备配置只需要修改map中的配置
	var gateway_id = reqdata.ParentId
	if _, ok := modbus.GatewayConn[gateway_id]; !ok {
		// 不存在，报错
		zaplog.Logger.Error("gateway not exist", zap.String("gateway_id", gateway_id))
		rspdata["code"] = 400
		rspdata["message"] = "gateway not exist"
	} else {
		// 获取子设备的key
		var sub_device_key = fmt.Sprintf("%d_%d_%d", reqdata.DeviceConfig.DeviceConfig.DeviceAddress, reqdata.DeviceConfig.DeviceConfig.FunctionCode, reqdata.DeviceConfig.DeviceConfig.StartingAddress)
		// 删除map中的key
		delete(modbus.GatewayConn[gateway_id].SubDeviceReqMap, sub_device_key)
	}

	data, err := json.Marshal(rspdata)
	if err != nil {
		log.Println(err.Error())
	}
	fmt.Fprint(w, string(data))
}
